package se.webbzon.boltzmann.game.object.spawner;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import se.webbzon.boltzmann.battle.environment.BattleEnvironment;
import se.webbzon.boltzmann.battle.property.BattlePropertyFactory;
import se.webbzon.boltzmann.debug.Debug;
import se.webbzon.boltzmann.environment.AbstractEnvironment;
import se.webbzon.boltzmann.game.character.CharacterException;
import se.webbzon.boltzmann.game.environment.GameEnvironment;
import se.webbzon.boltzmann.game.object.npc.HostileAI;
import se.webbzon.boltzmann.game.object.npc.HostileNPC;
import se.webbzon.boltzmann.npc.NPCDuty;
import se.webbzon.boltzmann.object.unknown.Unknown;
import se.webbzon.oschi01.worldeditor.WorldObjectDeflation;
import se.webbzon.oschi01.worldobject.WorldObject;
import se.webbzon.oschi01.worldobject.WorldStaticObject;

public class HostileNPCSpawner extends AbstractNPCSpawner {

	// The name of the deflatable world object
	public static final String worldObjectName = "hostileNPCSpawner";
	
	// The artificial intelligence of the spawned character
	private HostileAI ai;
	
	// The name of the world area in which the battle should occur
	private String worldAreaName;
	
	// A list of all the battle property factories used by the spawned npc
	private final List<BattlePropertyFactory> battlePropertyFactories;
	
	/*============================================================
	Constructors
	============================================================*/
	
	public HostileNPCSpawner(	long id, String key, 
								String characterTextureSetName,
								HostileAI ai, String worldAreaName) {
		super(worldObjectName,id,key,characterTextureSetName);
		this.ai = ai;
		this.worldAreaName = worldAreaName;
		battlePropertyFactories = new ArrayList<BattlePropertyFactory>();
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Returns the artificial intelligence enumeration of the spawned character. **/
	public HostileAI getAI() {
		return ai;
	}
	
	/** Returns the artificial intelligence enumeration of the spawned character. **/
	public void setAI(HostileAI ai) {
		this.ai = ai;
	}

	/** Returns the name of the world area in which the battle should occur. **/
	public String getWorldAreaName() {
		return worldAreaName;
	}

	/** Sets the name of the world area in which the battle should occur. **/
	public void setWorldAreaName(String worldAreaName) {
		this.worldAreaName = worldAreaName;
	}
	
	/** Adds a new battle property factory to the spawner. **/
	public boolean addBattlePropertyFactory(BattlePropertyFactory factory) {
		return battlePropertyFactories.add(factory);
	}
	
	/** Removes a new battle property factory from the spawner. **/
	public boolean removeBattlePropertyFactory(BattlePropertyFactory factory) {
		return battlePropertyFactories.remove(factory);
	}
	
	/** Clears all the battle property factories in the spawner. **/
	public void clearBattlePropertyFactories() {
		battlePropertyFactories.clear();
	}
	
	/** Returns a list of all the battle property factories used by
	 * the npc associated with this spawner. **/
	public List<BattlePropertyFactory> getBattlePropertyFactories() {
		return Collections.unmodifiableList(battlePropertyFactories);
	}

	@Override public WorldObjectDeflation getDeflation() {
		return new HostileNPCSpawnerDeflation(0,this);
	}

	@Override public WorldObject spawn(AbstractEnvironment env) {
		WorldStaticObject instance;
		NPCDuty d = null;
		double dy = 0.5;
		if (env instanceof GameEnvironment) try {
			GameEnvironment genv = (GameEnvironment) env;
			BattleEnvironment benv = genv.getBattleEnvironment();
			HostileNPC npc = new HostileNPC(getCharacterTextureSetName(),benv,ai,
					battlePropertyFactories,worldAreaName);
			d = npc.getDuty();
			instance = npc;
		} catch (CharacterException e) {
			Debug.report(e);
			instance = new Unknown();
		} else {
			instance = new Unknown();
		}
		
		instance.setPosition(getX(), getY()+dy, getZ());
		instance.setSize(getWidth(), getHeight(), getDepth());
		instance.setRotation(getEX(), getEY(), getEZ(), getAngle());
		if (d != null)
			d.setOrigin(getX(), getY(), getZ());
		
		return instance;
	}

}
